package main

import "fmt"

//结构体-方法
/*
1.方法就是给某个类型绑定一个函数
2.被绑定类型也作为一个参数
3.注意类型本身不能是指针
4.用户value和指针调用方法不受方法集约束，编译器会找到全部方法，并自动转换成接收者实参
*/

type User struct {
	name string
	sex  int
	age  int
}

type Student struct {
	User //继承了User
	id   int
	addr string
}

func (this *User) say(s string) {
	fmt.Println("user say: ", s)
}

func (this *Student) say(s string) {
	fmt.Println("student say: ", s)
}

//如果是拷贝参数，将不能改变对象本身
func (up *User) setName(name string) {
	up.name = name
}

func (up *User) getName() (n string) {
	n = up.name
	fmt.Println("getName :", n)
	return
}

func main() {
	u0 := &User{"tom", 1, 20}
	u0.setName("jack")
	u0.getName()
	fmt.Println("u0=", *u0)

	u1 := new(User)
	u1.setName("apple")
	u1.sex = 0
	u1.age = 22
	u1.getName()
	fmt.Println("u1=", *u1)

	s0 := new(Student)
	//继承类同样也继承了方法, 同名方法被重写，就近原则，先找本类方法，再找父类方法
	s0.say("i'm a student")
	//方法可以被赋值
	s0_say := s0.say
	s0_say("hello")
}
